package top.lemna.code.generate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import top.lemna.code.generate.util.JavaParserUtils;

/**
 * Dubbo生成器，会生成各种 dto bo mapper manager test
 * 
 * @author APPLE
 *
 */
public class DubboGenerator {
  private final String className;

  private final String domainName;

  private final String templatePath;

  // 输出的包名，与 @see outPath 对应
  private final String basePackage;

  // 输出的路径
  private final String outPath;

  private final String artifactName;

  public DubboGenerator(String className, String basePackage, String outPath, String templatePath) {
    super();
    this.className = className;
    this.templatePath = templatePath;
    this.outPath = outPath;
    this.basePackage = basePackage;
    this.artifactName = getArtifactName(basePackage);
    this.domainName = getDomainName(className);
  }

  public void generator() throws Exception {
    ClassElement classElement = JavaParserUtils.parserJava(className);
    List<JavaField> list = classElement.getFieldList();
    String classComment = classElement.getClassComment().replaceAll("<br>", "");

    Map<String, Object> dataMap = new HashMap<String, Object>();
    dataMap.put("classPath", basePackage);
    dataMap.put("classComment", classComment);
    dataMap.put("domain", domainName);
    dataMap.put("fieldList", list);
    dataMap.put("artifact", artifactName);


    // 生成 Repository
    generatorRepository(dataMap);
    // 生成 Service
    generatorService(dataMap);
    // 生成 BO
    generatorQueryBo(dataMap);
    generatorAddBo(dataMap);
    generatorEditBo(dataMap);
    // 生成 Command
    generatorAddCommand(dataMap);
    generatorEditCommand(dataMap);
    generatorQueryCommand(dataMap);
    // 生成 Controller
    generatorController(dataMap);
    // 生成 VO
    generatorVo(dataMap);
    // 生成 manager
    generatorDto(dataMap);
    generatorManager(dataMap);
    generatorManagerImpl(dataMap);
    generatorMapper(dataMap);
    generatorQueryDto(dataMap);
    // 生成测试用例
    generatorDomainTest(dataMap);
    generatorManagerImplTest(dataMap);
    generatorMapperTest(dataMap);
    generatorRepositoryTest(dataMap);
    generatorServiceTest(dataMap);

  }

  private void generatorRepository(Map<String, Object> dataMap) throws Exception {
    String templateName = "persistence/Repository.ftl";
    String outFilePath = outPath + "/service/repository/";
    String outFileName = domainName + "Repository.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorService(Map<String, Object> dataMap) throws Exception {
    String templateName = "persistence/Service.ftl";
    String outFilePath = outPath + "/service/service/";
    String outFileName = domainName + "Service.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorQueryBo(Map<String, Object> dataMap) throws Exception {
    String templateName = "persistence/Query.ftl";
    String outFilePath = outPath + "/service/query/";
    String outFileName = domainName + "Query.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorAddBo(Map<String, Object> dataMap) throws Exception {
    String templateName = "persistence/AddBo.ftl";
    String outFilePath = outPath + "/service/bo/";
    String outFileName = domainName + "AddBo.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorEditBo(Map<String, Object> dataMap) throws Exception {
    String templateName = "persistence/EditBo.ftl";
    String outFilePath = outPath + "/service/bo/";
    String outFileName = domainName + "EditBo.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorAddCommand(Map<String, Object> dataMap) throws Exception {
    String templateName = "web/AddCommand.ftl";
    String outFilePath = outPath + "/command/";
    String outFileName = domainName + "AddCommand.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorEditCommand(Map<String, Object> dataMap) throws Exception {
    String templateName = "web/EditCommand.ftl";
    String outFilePath = outPath + "/command/";
    String outFileName = domainName + "EditCommand.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }


  private void generatorQueryCommand(Map<String, Object> dataMap) throws Exception {
    String templateName = "web/QueryCommand.ftl";
    String outFilePath = outPath + "/command/";
    String outFileName = domainName + "QueryCommand.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }
 
  private void generatorController(Map<String, Object> dataMap) throws Exception {
    String templateName = "web/Controller.ftl";
    String outFilePath = outPath + "/controller/";
    String outFileName = domainName + "Controller.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }


  private void generatorVo(Map<String, Object> dataMap) throws Exception {
    String templateName = "web/Vo.ftl";
    String outFilePath = outPath + "/controller/vo/";
    String outFileName = domainName + "Vo.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorManager(Map<String, Object> dataMap) throws Exception {
    String templateName = "manager/Manager.ftl";
    String outFilePath = outPath + "/manager/";
    String outFileName = domainName + "Manager.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorManagerImpl(Map<String, Object> dataMap) throws Exception {
    String templateName = "manager/ManagerImpl.ftl";
    String outFilePath = outPath + "/manager/";
    String outFileName = domainName + "ManagerImpl.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorMapper(Map<String, Object> dataMap) throws Exception {
    String templateName = "manager/Mapper.ftl";
    String outFilePath = outPath + "/manager/";
    String outFileName = domainName + "Mapper.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorDto(Map<String, Object> dataMap) throws Exception {
    String templateName = "manager/Dto.ftl";
    String outFilePath = outPath + "/manager/";
    String outFileName = domainName + "Dto.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorQueryDto(Map<String, Object> dataMap) throws Exception {
    String templateName = "manager/QueryDto.ftl";
    String outFilePath = outPath + "/manager/";
    String outFileName = domainName + "QueryDto.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorDomainTest(Map<String, Object> dataMap) throws Exception {
    String templateName = "test/DomainTest.ftl";
    String outFilePath = outPath + "/test/";
    String outFileName = domainName + "TestBuilder.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorManagerImplTest(Map<String, Object> dataMap) throws Exception {
    String templateName = "test/ManagerImplTest.ftl";
    String outFilePath = outPath + "/test/";
    String outFileName = domainName + "ManagerImplTest.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorMapperTest(Map<String, Object> dataMap) throws Exception {
    String templateName = "test/MapperTest.ftl";
    String outFilePath = outPath + "/test/";
    String outFileName = domainName + "MapperTest.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorRepositoryTest(Map<String, Object> dataMap) throws Exception {
    String templateName = "test/RepositoryTest.ftl";
    String outFilePath = outPath + "/test/";
    String outFileName = domainName + "RepositoryTest.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }

  private void generatorServiceTest(Map<String, Object> dataMap) throws Exception {
    String templateName = "test/ServiceTest.ftl";
    String outFilePath = outPath + "/test/";
    String outFileName = domainName + "ServiceTest.java";
    FreemarkerGenerator fg = new FreemarkerGenerator(templatePath);
    fg.generator(dataMap, templateName, outFilePath, outFileName);
  }


  static String getDomainName(String className) {
    return className.replaceAll("\\\\", "/")
        .substring(className.lastIndexOf("/"), className.lastIndexOf(".")).replaceAll("/", "");
  }

  static String getArtifactName(String basePackage) {
    return basePackage.substring(basePackage.lastIndexOf(".") + 1);
  }
}
